package cn.xuyanwu.spring.file.storage.platform;

import cn.xuyanwu.spring.file.ContentTypeSpy;
import cn.xuyanwu.spring.file.storage.FileInfo;
import cn.xuyanwu.spring.file.storage.UploadPretreatment;
import com.microsoft.azure.storage.CloudStorageAccount;
import com.microsoft.azure.storage.blob.*;
import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
import org.springframework.util.StringUtils;

import java.io.InputStream;
import java.util.function.Consumer;

/**
 * @author lianglaibin
 */
@Getter
@Setter
public class AzureBlob8FileStorage implements FileStorage {
    /**
     * 存储平台
     */
    private String platform;
    private String containerName;
    private String connectionString;
    private String domain;
    private String basePath ;

    @SneakyThrows
    public CloudBlobClient getCloudBlobClient() {
        CloudStorageAccount cloudStorageAccount = CloudStorageAccount.parse(connectionString);
        CloudBlobClient cloudBlobClient = cloudStorageAccount.createCloudBlobClient();
        return cloudBlobClient;
    }
    @SneakyThrows
    public CloudBlobContainer getCloudBlobContainer() {
        CloudBlobClient cloudBlobClient = getCloudBlobClient();
        CloudBlobContainer cloudBlobContainer = cloudBlobClient.getContainerReference(containerName);
        cloudBlobContainer.createIfNotExists(BlobContainerPublicAccessType.CONTAINER, null, null);
        return cloudBlobContainer;
    }

    @SneakyThrows
    @Override
    public boolean save(FileInfo fileInfo, UploadPretreatment pre) {
        CloudBlobContainer cloudBlobContainer = getCloudBlobContainer();
        String newFileKey = basePath + fileInfo.getPath() + fileInfo.getFilename();
        fileInfo.setBasePath(basePath);
        CloudBlockBlob cloudBlockBlob = cloudBlobContainer.getBlockBlobReference(newFileKey);
        if(StringUtils.hasText(domain)) {
            if("$root".equals(cloudBlobContainer.getName())) {
                // 参考：https://docs.microsoft.com/zh-cn/azure/storage/blobs/storage-blob-container-create?tabs=dotnet
                // 根容器充当存储帐户的默认容器。 每个存储帐户只能包含一个根容器，该容器必须命名为 $root。
                // 可以引用存储在根容器中的 Blob，而无需包含根容器名称。 根容器允许引用位于存储帐户层次结构顶层的 Blob。 例如，可通过以下方式引用根容器中的 blob：
                // https://myaccount.blob.core.windows.net/default.html
                fileInfo.setUrl(domain + newFileKey);
            } else {
                fileInfo.setUrl(domain + cloudBlobContainer.getName() + "/" + newFileKey);
            }
        }
        cloudBlockBlob.getProperties().setContentType(ContentTypeSpy.getContentTypeByFileName(fileInfo.getFilename()));
        cloudBlockBlob.upload(pre.getFileWrapper().getInputStream(), pre.getFileWrapper().getSize());
        if(fileInfo.getUrl() == null) {
            fileInfo.setUrl(cloudBlockBlob.getStorageUri().getPrimaryUri().toString());
        }
        return true;
    }

    @Override
    public boolean delete(FileInfo fileInfo) {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean exists(FileInfo fileInfo) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void download(FileInfo fileInfo, Consumer<InputStream> consumer) {
        throw new UnsupportedOperationException();
    }

    @Override
    public void downloadTh(FileInfo fileInfo, Consumer<InputStream> consumer) {
        throw new UnsupportedOperationException();
    }
}
